import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsArray,
  IsBoolean,
  IsNumber,
  IsObject,
  IsOptional,
  IsString,
  Max,
  Min,
} from 'class-validator';

/**
 * OpenRouter文本完成请求DTO
 */
export class OpenRouterCompletionRequestDto {
  /**
   * 要使用的模型ID
   */
  @ApiProperty({
    description: '要使用的模型ID',
    example: 'mistralai/mistral-7b-instruct',
  })
  @IsString()
  model: string;

  /**
   * 要完成的文本提示
   */
  @ApiProperty({
    description: '要完成的文本提示',
    example: '讲一个关于AI的短故事',
  })
  @IsString()
  prompt: string;

  /**
   * 是否启用结果流式传输
   */
  @ApiPropertyOptional({
    description: '是否启用结果流式传输',
    default: false,
    example: false,
  })
  @IsOptional()
  @IsBoolean()
  stream?: boolean;

  /**
   * 最大生成令牌数
   */
  @ApiPropertyOptional({
    description: '生成响应的最大token数',
    minimum: 1,
    example: 1024,
  })
  @IsOptional()
  @IsNumber()
  @Min(1)
  max_tokens?: number;

  /**
   * 采样温度，控制输出的随机性
   */
  @ApiPropertyOptional({
    description: '采样温度，控制输出的随机性',
    minimum: 0,
    maximum: 2,
    default: 1,
    example: 0.7,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  temperature?: number;

  /**
   * 确定性输出的种子
   */
  @ApiPropertyOptional({
    description: '确定性输出的种子',
    example: 42,
  })
  @IsOptional()
  @IsNumber()
  seed?: number;

  /**
   * Top-p采样值
   */
  @ApiPropertyOptional({
    description: 'Top-p采样值',
    minimum: 0,
    maximum: 1,
    default: 1,
    example: 0.9,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(1)
  top_p?: number;

  /**
   * Top-k采样值
   */
  @ApiPropertyOptional({
    description: 'Top-k采样值',
    minimum: 1,
    example: 40,
  })
  @IsOptional()
  @IsNumber()
  @Min(1)
  top_k?: number;

  /**
   * 频率惩罚
   */
  @ApiPropertyOptional({
    description: '频率惩罚',
    minimum: -2,
    maximum: 2,
    default: 0,
    example: 0,
  })
  @IsOptional()
  @IsNumber()
  @Min(-2)
  @Max(2)
  frequency_penalty?: number;

  /**
   * 存在惩罚
   */
  @ApiPropertyOptional({
    description: '存在惩罚',
    minimum: -2,
    maximum: 2,
    default: 0,
    example: 0,
  })
  @IsOptional()
  @IsNumber()
  @Min(-2)
  @Max(2)
  presence_penalty?: number;

  /**
   * 重复惩罚
   */
  @ApiPropertyOptional({
    description: '重复惩罚',
    minimum: 0,
    maximum: 2,
    example: 1.1,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(2)
  repetition_penalty?: number;

  /**
   * 词元ID到偏置值的映射
   */
  @ApiPropertyOptional({
    description: '词元ID到偏置值的映射',
    type: 'object',
    example: { '50256': -100 },
  })
  @IsOptional()
  @IsObject()
  logit_bias?: Record<string, number>;

  /**
   * 返回的顶部日志概率数
   */
  @ApiPropertyOptional({
    description: '返回的顶部日志概率数',
    minimum: 0,
    example: 5,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  top_logprobs?: number;

  /**
   * 最小概率阈值
   */
  @ApiPropertyOptional({
    description: '最小概率阈值',
    minimum: 0,
    maximum: 1,
    example: 0.05,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(1)
  min_p?: number;

  /**
   * 备用顶部采样参数
   */
  @ApiPropertyOptional({
    description: '备用顶部采样参数',
    minimum: 0,
    maximum: 1,
    example: 0.8,
  })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Max(1)
  top_a?: number;

  /**
   * 提示转换列表（仅限OpenRouter）
   */
  @ApiPropertyOptional({
    description: '提示转换列表（仅限OpenRouter）',
    type: [String],
    example: ['format_for_claude'],
  })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  transforms?: string[];

  /**
   * 路由覆盖的模型列表
   */
  @ApiPropertyOptional({
    description: '路由覆盖的模型列表',
    type: [String],
    example: ['anthropic/claude-3-sonnet'],
  })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  models?: string[];

  /**
   * 模型路由策略（仅限OpenRouter）
   */
  @ApiPropertyOptional({
    description: '模型路由策略（仅限OpenRouter）',
    default: 'fallback',
    example: 'fallback',
  })
  @IsOptional()
  @IsString()
  route?: string;

  /**
   * 提供商路由的首选项
   */
  @ApiPropertyOptional({
    description: '提供商路由的首选项',
    type: 'object',
  })
  @IsOptional()
  @IsObject()
  provider?: Record<string, any>;

  /**
   * 模型推理/思考令牌的配置
   */
  @ApiPropertyOptional({
    description: '模型推理/思考令牌的配置',
    type: 'object',
  })
  @IsOptional()
  @IsObject()
  reasoning?: Record<string, any>;
}
